package jlfm.lastfm.tools.mb;

import java.util.List;

import jlfm.lastfm.apps.ID3MetadataProvider;
import jlfm.lastfm.client.LastFmClientFaultException;
import jlfm.lastfm.client.TrackMetadata;
import jlfm.lastfm.client.impl.simple.ProxyConfiguration;
import jlfm.lastfm.tools.id3.ID3Metadata;
import jlfm.lastfm.tools.id3.LastFmMetadataWrapper;

import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.musicbrainz.JMBWSException;
import org.musicbrainz.Query;
import org.musicbrainz.model.Artist;
import org.musicbrainz.model.Release;
import org.musicbrainz.model.Track;
import org.musicbrainz.webservice.filter.TrackFilter;
import org.musicbrainz.webservice.impl.HttpClientWebService;
import org.musicbrainz.webservice.includes.ArtistIncludes;
import org.musicbrainz.webservice.includes.ReleaseIncludes;
import org.musicbrainz.wsxml.element.TrackResult;
import org.musicbrainz.wsxml.element.TrackSearchResults;

public class MusicBrainzImpl implements ID3MetadataProvider {

	ProxyConfiguration proxyConfiguration = new ProxyConfiguration();

	public MusicBrainzImpl() {
	}

	public MusicBrainzImpl(ProxyConfiguration proxyConfiguration) {
		this.proxyConfiguration = proxyConfiguration;
	}

	public ID3Metadata getID3Metadata(TrackMetadata trackMetadata) {
		try {
			Track track = getTrack(trackMetadata.getArtist(), trackMetadata
					.getTrack());
			Release album = null;
			Artist artist = null;
			if (track != null) {
				album = getAlbum(track);
				artist = getArtist(track);
				return new MusicBrainzMetadataWrapper(track, album, artist);
			}
			return new LastFmMetadataWrapper(trackMetadata);

		} catch (JMBWSException e) {
			e.printStackTrace();
			throw new LastFmClientFaultException(e);
		}
	}

	public void setProxyConfiguration(ProxyConfiguration proxyConfiguration) {
		this.proxyConfiguration = proxyConfiguration;
	}

	private Artist getArtist(Track t) throws JMBWSException {
		if (t.getArtist() != null) {
			return getArtist(t.getArtist().getId());
		}
		return null;
	}

	private Release getAlbum(Track t) throws JMBWSException {
		if (t.getReleases().size() > 0) {
			return getAlbum(t.getReleases().get(0).getId());
		}
		return null;

	}

	private Track getTrack(String artist, String trackName)
			throws JMBWSException {
		Query q = createQuery();
		TrackFilter trackFilter = new TrackFilter();
		trackFilter.setArtistName(artist);
		trackFilter.setTitle(trackName);
		// TODO Evtl. Duration als Kriterium setzen
		trackFilter.setLimit((long) 1);

		TrackSearchResults results;
		results = q.getTracks(trackFilter);
		List<TrackResult> resultList = results.getTrackResults();
		Track track = null;
		if (resultList.size() > 0) {
			track = resultList.get(0).getTrack();
		}
		return track;
	}

	private Release getAlbum(String albumId) throws JMBWSException {
		ReleaseIncludes i = new ReleaseIncludes();
		i.setDiscs(true);
		i.setReleaseEvents(true);

		Query q = createQuery();
		return q.getReleaseById(albumId, i);
	}

	private Artist getArtist(String artistId) throws JMBWSException {
		ArtistIncludes i = new ArtistIncludes();
		Query q = createQuery();
		return q.getArtistById(artistId, i);
	}

	private Query createQuery() {
		HttpClient httpClient = new HttpClient();
		if (proxyConfiguration.isUseProxy()) {
			HostConfiguration hc = new HostConfiguration();
			hc.setProxy(proxyConfiguration.getProxyHost(), proxyConfiguration
					.getProxyPort());
			httpClient.setHostConfiguration(hc);
		}

		HttpClientWebService ws = new HttpClientWebService(httpClient);

		return new Query(ws);
	}

}
